home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / dviware / dvitops / dvi.c < prev    next >
C/C++ Source or Header  |  1991-01-25  |  15KB  |  626 lines

  1. static char rcsid[] = "$Header: /usr/jjc/dvitops/RCS/dvi.c,v 1.6 90/08/14 13:09:18 jjc Rel $";
  2.  
  3. #include "dvitops.h"
  4.  
  5.  
  6. static struct stack {
  7.     integer h, v, w, x, y, z;
  8. } *stack;
  9.  
  10.  
  11.  
  12. struct addr_count0 { 
  13.     integer addr; 
  14.     integer count0; 
  15. }; 
  16. struct postamble_info {
  17.     integer num;
  18.     integer den;
  19.     int mag;
  20.     integer last_bop; /* address of last bop */
  21.     int npages;
  22.     int stack_size;
  23. };
  24.  
  25.  
  26. #ifdef PROTO
  27. static void first_pass(int, long *, int, struct addr_count0 *);
  28. static void read_page(struct page_info *page);
  29. static int read_opcode(void);
  30. static void read_postamble(struct postamble_info *postamble);
  31. static void bad_dvi_file(void);
  32. static int count_compare(char *p1, char *p2);
  33. #else
  34. static void first_pass();
  35. static void read_page();
  36. static int read_opcode();
  37. static void read_postamble();
  38. static void bad_dvi_file();
  39. static int count_compare();
  40. #endif
  41. #if 0
  42. typedef enum { SET_CHAR_0 = 0, SET1 = 128, SET_RULE = 132, PUT1 = 133,
  43. PUT_RULE = 137, BOP = 139, EOP = 140, PUSH = 141, POP = 142, RIGHT1 = 143,
  44. W0 = 147, W1 = 148, X0 = 152, X1 = 153, DOWN1 = 157, Y0 = 161, Y1 = 162,
  45. Z0 = 166, Z1 = 167, FNT_NUM_0 = 171, FNT1 = 235, NOP = 138, XXX1 = 239,
  46. FNT_DEF1 = 243, PRE = 247, POST = 248, POST_POST = 249 } dvi_opcode;
  47. #else
  48. #define SET_CHAR_0  0
  49. #define SET1  128
  50. #define SET_RULE  132
  51. #define PUT1  133
  52. #define PUT_RULE  137
  53. #define BOP  139
  54. #define EOP  140
  55. #define PUSH  141
  56. #define POP  142
  57. #define RIGHT1  143
  58. #define W0  147
  59. #define W1  148
  60. #define X0  152
  61. #define X1  153
  62. #define DOWN1  157
  63. #define Y0  161
  64. #define Y1  162
  65. #define Z0  166
  66. #define Z1  167
  67. #define FNT_NUM_0  171
  68. #define FNT1  235
  69. #define NOP  138
  70. #define XXX1  239
  71. #define FNT_DEF1  243
  72. #define PRE  247
  73. #define POST  248
  74. #define POST_POST  249 
  75. #endif
  76.  
  77. static FILE *dvifp;
  78.  
  79. #define SPECIAL_BUF_SIZE 2048
  80. static char special_buf[SPECIAL_BUF_SIZE];
  81.  
  82.  
  83. static void first_pass(totalpages, start_page, maxpages, pagevec)
  84. int totalpages, maxpages;
  85. long start_page[10];
  86. struct addr_count0 *pagevec;
  87. {
  88.     integer count[10];
  89.     int pageno;
  90.     int started = FALSE;
  91.     int selected = FALSE;
  92.     int pages_selected = 0;
  93.     fseek(dvifp, 14L, 0);
  94.     if (fseek(dvifp, (long)uread1(dvifp), 1) != 0)
  95.         bad_dvi_file();
  96.     for (pageno = 0; pageno < totalpages; pageno++) {
  97.         unsigned char opcode;
  98.         int i;
  99.         int donepage = FALSE;
  100.         int f = -1;
  101.         pagevec[pageno].addr = ftell(dvifp);
  102.         while (!donepage) {
  103.             unsigned char c;
  104.             integer n = 0;
  105.             /* deal with the most common case in its own loop */
  106.             while ((opcode = uread1(dvifp)) <= 127) {
  107.                 if (feof(dvifp) || ferror(dvifp))
  108.                     bad_dvi_file();
  109.                 if (selected)
  110.                     used_char(f, opcode);
  111.             }
  112.             /* we use the fact that SET_CHAR_0 is 0 */
  113.  
  114.             if (FNT_NUM_0 <= opcode && opcode <= FNT_NUM_0 + 63) {
  115.                 n  = opcode - FNT_NUM_0;
  116.                 opcode = FNT1;
  117.             }
  118.             else
  119.                 switch (opcode) {
  120.                 case SET1 + 3 : case PUT1 + 3 : case XXX1 + 3:
  121.                 case FNT_DEF1 + 3: case FNT1 + 3:
  122.                     n = sread4(dvifp); break;
  123.                 case SET1 + 2 : case PUT1 + 2 : case XXX1 + 2:
  124.                 case FNT_DEF1 + 2: case FNT1 + 2:
  125.                     n = uread3(dvifp); break;
  126.                 case SET1 + 1 : case PUT1 + 1 : case XXX1 + 1:
  127.                 case FNT_DEF1 + 1: case FNT1 + 1:
  128.                     n = uread2(dvifp); break;
  129.                 case SET1 : case PUT1 : case XXX1:
  130.                 case FNT_DEF1: case FNT1:
  131.                     n = uread1(dvifp); break;
  132.                 case RIGHT1 + 3: case W1 + 3: case X1 + 3:
  133.                 case DOWN1 + 3: case Y1 + 3: case Z1 + 3:
  134.                     (void)uread1(dvifp);
  135.                 /* falls through */
  136.                 case RIGHT1 + 2: case W1 + 2: case X1 + 2:
  137.                 case DOWN1 + 2: case Y1 + 2: case Z1 + 2:
  138.                     (void)uread1(dvifp);
  139.                     /* falls through */
  140.                 case RIGHT1 + 1: case W1 + 1: case X1 + 1:
  141.                 case DOWN1 + 1: case Y1 + 1: case Z1 + 1:
  142.                     (void)uread1(dvifp);
  143.                     /* falls through */
  144.                 case RIGHT1: case W1: case X1:
  145.                 case DOWN1: case Y1: case Z1:
  146.                     (void)uread1(dvifp);
  147.                     break;
  148.                 case SET_RULE: case PUT_RULE :
  149.                     sread4(dvifp); sread4(dvifp);
  150.                     break;
  151.                 }
  152.                 switch (opcode) {
  153.                 case SET1 + 3 : case SET1 + 2 : case SET1 + 1 : case SET1 :
  154.                 case PUT1 + 3 : case PUT1 + 2 : case PUT1 + 1 : case PUT1 :
  155.                     if (!selected)
  156.                         break;
  157.                     c = (unsigned char) n;
  158.                     if (n >= MAXCHARS || n < 0)
  159.                         message(ERROR, 
  160.                             "character code %ld too large: using %d instead", 
  161.                                                                 (long)n, c);
  162.                     used_char(f, c);
  163.                     break;
  164.                 case BOP :
  165.                     for (i = 0; i < 10; ++i)
  166.                         count[i] = sread4(dvifp);
  167.                     pagevec[pageno].count0 = count[0];
  168.                     (void) sread4(dvifp);
  169.                     if (!started) {
  170.                         int j;
  171.                         started = TRUE;
  172.                         for (j = 0; j < 10; j++)
  173.                             if (start_page[j] != WILD
  174.                                     && start_page[j] != count[j])
  175.                                 started = FALSE;
  176.                     }
  177.                     if (started && ++pages_selected <= maxpages)
  178.                         selected = TRUE;
  179.                     else {
  180.                         selected = FALSE;
  181.                         pagevec[pageno].addr = -1;
  182.                     }
  183.                     break;
  184.                 case EOP :
  185.                     if (selected)
  186.                         store_page_usage();
  187.                     donepage = TRUE;
  188.                     break;
  189.                 case FNT1 : case FNT1 + 1 : case FNT1 + 2 : case FNT1 + 3 :
  190.                     if (!selected)
  191.                         break;
  192.                     if (n < 0 || n >= MAXFONTS)
  193.                         /* this should have been spotted in the postamble */
  194.                         cant_happen();
  195.                     f = (int) n;
  196.                     break;
  197.                 case XXX1 + 3 : case XXX1 + 2 : case XXX1 + 1 : case XXX1:
  198.                     if (n >= SPECIAL_BUF_SIZE) {
  199.                         message(ERROR, 
  200.                             "special string too long: ignoring it");
  201.                         fseek(dvifp, (long)n, 1);
  202.                         break;
  203.                     }
  204.                     fread(special_buf, 1, (size_t)n, dvifp);
  205.                     special_buf[n] = '\0';
  206.                     STRXCHAR(special_buf)
  207.                     if (selected)
  208.                         special(PASS1, special_buf,(integer)0,(integer)0);
  209.                     break;
  210.                 case FNT_DEF1 : case FNT_DEF1 + 1 :
  211.                 case FNT_DEF1 + 2 : case FNT_DEF1 + 3 :
  212.                     fseek(dvifp, 12L, 1);            
  213.                     n = uread1(dvifp);
  214.                     n += uread1(dvifp);
  215.                     fseek(dvifp, (long)n, 1);
  216.                     break;
  217.                 case POST :
  218.                     bad_dvi_file();
  219.                 default :
  220.                     break;
  221.                 }
  222.         }
  223.     }
  224. }
  225.  
  226. static int read_opcode()
  227. {
  228.     for (;;) {
  229.         int c = uread1(dvifp);
  230.         if (c == EOF)
  231.             cant_happen();
  232.         if (XXX1 <= c && c <= XXX1 + 3) {
  233.             integer k;
  234.             switch (c) {
  235.             case XXX1 :
  236.                 k = uread1(dvifp); break;
  237.             case XXX1 + 1:
  238.                 k = uread2(dvifp); break;
  239.             case XXX1 + 2:
  240.                 k = uread3(dvifp); break;
  241.             case XXX1 + 3:
  242.                 k = sread4(dvifp); break;
  243.             }
  244.             fseek(dvifp, (long)k, 1);
  245.         }
  246.         else if (c != NOP)
  247.             return c;
  248.     }
  249. }
  250.  
  251.  
  252. static void read_postamble(postamble)
  253. struct postamble_info *postamble;
  254. {
  255.     int c;
  256.     integer n;
  257.     long offset;
  258.     /* Avoid using a negative offset.
  259.        Some implementations can't handle this. */
  260.     if (fseek(dvifp, 0L, 2) != 0)
  261.         message(FATAL_ERROR, "can't perform seek on dvi file");
  262.     offset = ftell(dvifp);
  263.     do {
  264.         offset--;
  265.         fseek(dvifp, offset, 0);
  266.         c = uread1(dvifp);
  267.     } while (c == 223);
  268.     if (c != ID_BYTE)
  269.           message(FATAL_ERROR, "this is the wrong type of dvi file");
  270.     offset -= 5;
  271.     fseek(dvifp, offset, 0);
  272.     if (uread1(dvifp) != POST_POST) 
  273.         cant_happen();
  274.     offset = sread4(dvifp);
  275.     fseek(dvifp, offset, 0);
  276.     if (uread1(dvifp) != POST)
  277.         cant_happen();
  278.     postamble->last_bop = sread4(dvifp);
  279.     postamble->num = sread4(dvifp);
  280.     postamble->den = sread4(dvifp);
  281.     n = sread4(dvifp);
  282.     if (postamble->mag == 0) {
  283.         postamble->mag = (int)n;
  284.         if (n < 0 || n > INT_MAX) {
  285.             message(ERROR, "bad magnification: using 1000 instead");
  286.             n = 1000;
  287.         }
  288.     }
  289.     (void) sread4(dvifp);
  290.     (void) sread4(dvifp);
  291.     postamble->stack_size = sread2(dvifp);
  292.     postamble->npages = sread2(dvifp);
  293.     while ((c = read_opcode()) >= FNT_DEF1 && c <= FNT_DEF1 + 3) {
  294.         integer k;
  295.         integer cs, s, d;
  296.         int a, l;
  297.         char area[257];
  298.         char name[257];
  299.         switch (c + 1 - FNT_DEF1) {
  300.         case 1:
  301.             k = uread1(dvifp); break;
  302.         case 2:
  303.             k = uread2(dvifp); break;
  304.         case 3:
  305.             k = uread3(dvifp); break;
  306.         case 4:
  307.             k = sread4(dvifp); break;
  308.         }
  309.         cs = sread4(dvifp);
  310.         s = sread4(dvifp);
  311.         d = sread4(dvifp);
  312.         a = uread1(dvifp);
  313.         l = uread1(dvifp);
  314.         if (a)
  315.             fread(area, 1, a, dvifp);
  316.         area[a] = '\0';
  317.         fread(name, 1, l, dvifp);
  318.         name[l] = '\0';
  319.         STRXCHAR(name)
  320.         STRXCHAR(area)
  321.         f_def(k, name, area, cs, s, d, postamble->mag);
  322.     }
  323.     if (c != POST_POST)
  324.         cant_happen();
  325. }
  326.  
  327.  
  328. static int count_compare(p1, p2)
  329. char *p1, *p2;
  330. {
  331.     integer n1 = ((struct addr_count0 *)p1)->count0;
  332.     integer n2 = ((struct addr_count0 *)p2)->count0;
  333.     if (n1 == n2)
  334.         return (int)(((struct addr_count0 *)p1)->addr -
  335.                 ((struct addr_count0 *)p2)->addr);
  336.     else if (n1 <= 0 || n2 <= 0) {
  337.         if (n2 > 0)
  338.             return -1;
  339.         else if (n1 > 0)
  340.             return 1;
  341.         else
  342.             return (int)(n2 - n1);
  343.     }
  344.     else
  345.         return (int)(n1 - n2);
  346. }
  347.             
  348.  
  349.  
  350. void read_dvi_file(fp, ofp, option)
  351. FILE *fp, *ofp;
  352. struct option_info *option;
  353. {
  354.     struct postamble_info postamble;
  355.     struct page_info page;
  356.     FILE *psfp;
  357.     int i;
  358.     int actual_npages;
  359.     struct addr_count0 *pagevec;
  360.     dvifp = fp;
  361.     postamble.mag = option->mag;
  362.     read_postamble(&postamble);
  363.     if ((stack = 
  364.         (struct stack *)malloc(sizeof(struct stack)*postamble.stack_size))
  365.                             == NULL)
  366.         out_of_memory();
  367.     if ((pagevec = (struct addr_count0 *)malloc((1 + postamble.npages)
  368.                     *sizeof(struct addr_count0))) == NULL)
  369.         out_of_memory();
  370.     first_pass(postamble.npages, option->start_page, option->maxpages, 
  371.         pagevec);
  372.     psfp = ofp;
  373. #ifdef HAVE_SETVBUF
  374.     setvbuf(psfp, (char *)NULL, _IOFBF, 16384); /* ignore any error */
  375. #endif
  376.     for (i = 0, actual_npages = 0; i < postamble.npages; i++)
  377.         if (pagevec[i].addr != -1L)
  378.             actual_npages++;
  379.     prologue(psfp, actual_npages, option->reverse, option->paper);
  380.     page.num = postamble.num;
  381.     page.den = postamble.den;
  382.     page.hoffset = option->hoffset;
  383.     page.voffset = option->voffset;
  384.     page.copies = option->copies;
  385.     page.paper = option->paper;
  386.     page.max_drift = (int)((254000.0/page.num) * (page.den/(double)dpi) * 2.0);
  387.     if (option->sort)
  388.         qsort((char *)pagevec, postamble.npages, sizeof(struct addr_count0),
  389.                                 count_compare);
  390.     if (option->reverse) {
  391.         for (i = postamble.npages - 1; i >= 0; i--)
  392.             if (pagevec[i].addr != -1L) {
  393.                 page.address = pagevec[i].addr;
  394.                 page.mag = postamble.mag;
  395.                 read_page(&page);
  396.             }
  397.     }
  398.     else {
  399.         for (i = 0; i < postamble.npages; i++)
  400.             if (pagevec[i].addr != -1L) {
  401.                 page.address = pagevec[i].addr;
  402.                 page.mag = postamble.mag;
  403.                 read_page(&page);
  404.             }
  405.     }
  406.     trailer();
  407. }
  408.  
  409. static void read_page(page)
  410. struct page_info *page;
  411. {
  412.     unsigned char opcode;
  413.     int had_large_hmotion = FALSE;
  414.     int i;
  415.     char buf[512];
  416.     int nbuf = 0; /* number of characters in buf */
  417.     integer endh = 0, rounded_endh = 0;
  418.     integer h, v, w, x, y, z;
  419.     struct stack *sp = stack;
  420.     int f = -1;
  421.     integer fs = 0; /* = f_space(f) */
  422.     h = v = w = x = y = z = 0;
  423.  
  424.     fseek(dvifp, (long)page->address, 0);
  425.     for (;;) {
  426.         integer starth;
  427.         integer startv;
  428.         int startf;
  429.         unsigned char c;
  430.         integer a, b;
  431.         integer wd;
  432.         integer n = (integer)0;
  433.         opcode = uread1(dvifp);
  434.         /* we use the fact that SET_CHAR_0 is 0 */
  435.         if (opcode <= 127) {
  436.             /* we checked for eof and error on pass 1 */
  437.             n = opcode;
  438.             opcode = SET1;
  439.         }
  440.         else if (FNT_NUM_0 <= opcode && opcode <= FNT_NUM_0 + 63) {
  441.             n  = opcode - FNT_NUM_0;
  442.             opcode = FNT1;
  443.         }
  444.         else
  445.             switch (opcode) {
  446.             case SET1 + 3 : case PUT1 + 3 : case XXX1 + 3:
  447.             case RIGHT1 + 3: case W1 + 3: case X1 + 3:
  448.             case DOWN1 + 3: case Y1 + 3: case Z1 + 3:
  449.             case FNT_DEF1 + 3: case FNT1 + 3:
  450.                 n = sread4(dvifp); break;
  451.             case SET1 + 2 : case PUT1 + 2 : case XXX1 + 2:
  452.             case FNT_DEF1 + 2: case FNT1 + 2:
  453.                 n = uread3(dvifp); break;
  454.             case SET1 + 1 : case PUT1 + 1 : case XXX1 + 1:
  455.             case FNT_DEF1 + 1: case FNT1 + 1:
  456.                 n = uread2(dvifp); break;
  457.             case SET1 : case PUT1 : case XXX1:
  458.             case FNT_DEF1: case FNT1:
  459.                 n = uread1(dvifp); break;
  460.             case RIGHT1 + 2: case W1 + 2: case X1 + 2:
  461.             case DOWN1 + 2: case Y1 + 2: case Z1 + 2:
  462.                 n = sread3(dvifp); break;
  463.             case RIGHT1 + 1: case W1 + 1: case X1 + 1:
  464.             case DOWN1 + 1: case Y1 + 1: case Z1 + 1:
  465.                 n = sread2(dvifp); break;
  466.             case RIGHT1: case W1: case X1:
  467.             case DOWN1: case Y1: case Z1:
  468.                 n = sread1(dvifp); break;
  469.             }
  470.         switch (opcode) {
  471.         case SET1 + 3 : case SET1 + 2 : case SET1 + 1 : case SET1 :
  472.         case PUT1 + 3 : case PUT1 + 2 : case PUT1 + 1 : case PUT1 :
  473.             /* we checked it wasn't out of range on pass 1 */
  474.             c = (unsigned char)n;
  475.             if (nbuf > 0 &&
  476.                 (h != endh || v != startv || f != startf 
  477.                     || had_large_hmotion
  478.                     || nbuf >= sizeof(buf)
  479.                     || endh - rounded_endh > page->max_drift
  480.                     || endh - rounded_endh < -page->max_drift)) {
  481.                 set_string(buf, nbuf, startf, starth, startv);
  482.                 nbuf = 0;
  483.             }
  484.             if (nbuf == 0) {
  485.                 if (endh != rounded_endh && !had_large_hmotion) {
  486.                     if (rounded_endh - endh > page->max_drift)
  487.                         starth = h + page->max_drift;
  488.                     else if (rounded_endh - endh  < -page->max_drift)
  489.                         starth = h - page->max_drift;
  490.                     else
  491.                         starth = h + (rounded_endh - endh);
  492.                 }
  493.                 else
  494.                     starth = h;
  495.                 endh = h;
  496.                 rounded_endh = starth;
  497.                 startv = v;
  498.                 startf = f;
  499.                 had_large_hmotion = FALSE;
  500.             }
  501.             buf[nbuf++] = c;
  502.             used_char(f, c);
  503.             wd = f_width(f, c);
  504.             endh += wd;
  505.             rounded_endh += f_rounded_width(f, c);
  506.             /* we rely on the fact that SET1 < PUT1 */
  507.             if (opcode < PUT1)
  508.                 h += wd;
  509.             break;
  510.         case SET_RULE : case PUT_RULE :
  511.             a = sread4(dvifp);
  512.             b = sread4(dvifp);
  513.             set_rule(a, b, h, v);
  514.             if (opcode == SET_RULE)
  515.                 h += b;
  516.             break;
  517.         case NOP :
  518.             break;
  519.         case BOP :
  520.             for (i = 0; i < 10; ++i)
  521.                 page->count[i] = sread4(dvifp);
  522.             (void) sread4(dvifp);
  523.             break;
  524.         case EOP :
  525.             if (nbuf)
  526.                 set_string(buf, nbuf, startf, starth, startv);
  527.             eop(page);
  528.             return;
  529.         case PUSH :
  530.             sp->h = h; sp->v = v; sp->w = w;
  531.             sp->x = x; sp->y = y; sp->z = z;
  532.             ++sp;
  533.             break;
  534.         case POP :
  535.             --sp;
  536.             h = sp->h; v = sp->v; w = sp->w;
  537.             x = sp->x; y = sp->y; z = sp->z;
  538.             break;
  539.         case RIGHT1 : case RIGHT1 + 1 :
  540.         case RIGHT1 + 2 : case RIGHT1 + 3 :
  541.             h += n; 
  542.             if (n >= fs || n <= fs*-4)
  543.                 had_large_hmotion = TRUE;
  544.             break;
  545.         case W0 :
  546.             h += w;
  547.             break;
  548.         case W1 : case W1 + 1 : case W1 + 2 : case W1 + 3 :
  549.             h += w = n;
  550.             break;
  551.         case X0 :
  552.             h += x;
  553.             break;
  554.         case X1 : case X1 + 1 : case X1 + 2 : case X1 + 3 :
  555.             h += x = n;
  556.             break;
  557.         case DOWN1 : case DOWN1 + 1 : case DOWN1 + 2 : case DOWN1 + 3:
  558.             v += n;
  559.             break;
  560.         case Y0 :
  561.             v += y;
  562.             break;
  563.         case Y1 : case Y1 + 1 : case Y1 + 2 : case Y1 + 3 :
  564.             v += y = n;
  565.             break;
  566.         case Z0 :
  567.             v += z;
  568.             break;
  569.         case Z1 : case Z1 + 1 : case Z1 + 2 : case Z1 + 3 :
  570.             v += z = n;
  571.             break;
  572.         case FNT1 : case FNT1 + 1 : case FNT1 + 2 : case FNT1 + 3 :
  573.             if (n < 0 || n >= MAXFONTS)
  574.                 /* this should have caused a fatal error on pass 1 */
  575.                 cant_happen(); 
  576.             f = (int)n;
  577.             fs = f_space(f);
  578.             break;
  579.         case XXX1 + 3 : case XXX1 + 2 : case XXX1 + 1 : case XXX1 :
  580.             if (n >= SPECIAL_BUF_SIZE) {
  581.                 /* we printed an error on the first pass */
  582.                 fseek(dvifp, (long)n, 1);
  583.                 break;
  584.             }
  585.             if (nbuf > 0) { /* flush buf */
  586.                 set_string(buf, nbuf, startf, starth, startv);
  587.                 nbuf = 0;
  588.             }
  589.             fread(special_buf, 1, (int)n, dvifp);
  590.             special_buf[n] = '\0';
  591.             STRXCHAR(special_buf)
  592.             special(PASS2, special_buf, h, v);
  593.             break;
  594.         case FNT_DEF1 : case FNT_DEF1 + 1 :
  595.         case FNT_DEF1 + 2 : case FNT_DEF1 + 3 :
  596.             fseek(dvifp, 12L, 1);            
  597.             n = uread1(dvifp);
  598.             n += uread1(dvifp);
  599.             fseek(dvifp, (long)n, 1);
  600.             break;
  601.         case POST :
  602.             if (nbuf)
  603.                 set_string(buf, nbuf, startf, starth, startv);
  604.             return;
  605.         default :
  606.             bad_dvi_file();
  607.         }
  608.     }
  609. }            
  610.  
  611. static void bad_dvi_file()
  612. {
  613.     message(FATAL_ERROR, "this dvi file is bad -- use dvitype");
  614. }
  615.  
  616. /*
  617. Local Variables:
  618. tab-width: 4
  619. c-indent-level: 4
  620. c-continued-statement-offset: 4
  621. c-brace-offset: -4
  622. c-argdecl-indent: 0
  623. c-label-offset: -4
  624. End:
  625. */
  626.